package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.exceptions.DbException;
import com.tianji.common.utils.*;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.QuestionAdminPageQuery;
import com.tianji.learning.domain.query.QuestionPageQuery;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author yp
 * @since 2024-07-23
 */
@Service
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {


    private final InteractionReplyMapper replyMapper;
    private final UserClient userClient;
    private final SearchClient searchClient;

    private final CourseClient courseClient;

    private final CatalogueClient catalogueClient;

    private final CategoryCache categoryCache;

    /**
     * 新增问题
     *
     * @param questDTO
     */
    @Override
    public void saveQuestion(QuestionFormDTO questDTO) {
        //1.得到当前用户
        Long userId = UserContext.getUser();
        if (userId == null) {
            return;
        }
        //2.把QuestionFormDTO转化为InteractionQuestion
        InteractionQuestion interactionQuestion = BeanUtils.copyBean(questDTO, InteractionQuestion.class);
        //3.设置userId;
        interactionQuestion.setUserId(userId);
        //保存
        save(interactionQuestion);

    }

    /**
     * 分页查询内容(客户端)
     *
     * @param pageQuery
     * @return
     */
    @Override
    public PageDTO<QuestionVO> queryQuesionPage(QuestionPageQuery pageQuery) {


        Long userId = UserContext.getUser();


        Long sectionId = pageQuery.getSectionId();
        Long courseId = pageQuery.getCourseId();
        Boolean onlyMine = pageQuery.getOnlyMine();
        if (sectionId == null && courseId == null) {
            throw new BizIllegalException("参数有误");
        }
        //2.分页查询hidden为false的问题，根据前端条件进行过滤
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, q -> !q.getProperty().equals("description"))
                .eq(InteractionQuestion::getHidden, false)
                .eq(courseId != null, InteractionQuestion::getCourseId, courseId)
                .eq(sectionId != null, InteractionQuestion::getSectionId, sectionId)
                .eq(BooleanUtils.isTrue(onlyMine), InteractionQuestion::getUserId, userId)
                .page(pageQuery.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        Set<Long> userIds = new HashSet<>();
        Set<Long> answerIds = new HashSet<>();
        for (InteractionQuestion question : records) {
            if (!question.getAnonymity()) {
                userIds.add(question.getUserId());
            }//提问者的用户id
            answerIds.add(question.getLatestAnswerId());
        }

        //3.根据Lastet_answer_id 批量查询最近一次回答信息
        answerIds.remove(null);
        Map<Long, InteractionReply> replyMap = new HashMap<>();

        if (CollUtils.isNotEmpty(answerIds)) {
            List<InteractionReply> replyList = replyMapper.selectBatchIds(answerIds);
            if (CollUtils.isNotEmpty(replyList)) {
                for (InteractionReply reply : replyList) {
                    replyMap.put(reply.getId(), reply);
                    if (!reply.getAnonymity()) {
                        userIds.add(reply.getUserId());
                    }
                }
            }
        }
        //4.根据user_id批量查询用户信息
        Map<Long, UserDTO> userMap = new HashMap<>();
        userIds.remove(null);
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        if (CollUtils.isNotEmpty(userDTOS)) {
            userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        }
        //5.封装QuestionVO
        List<QuestionVO> voList = new ArrayList<>();
        for (InteractionQuestion question : records) {
            //每遍历一次,就封装一次QuestionVO对象
            QuestionVO vo = BeanUtils.copyBean(question, QuestionVO.class);
            //5.1.封装提问者的信息
            if (!question.getAnonymity()) {
                UserDTO user = userMap.get(question.getUserId());
                if (user != null) {
                    vo.setUserName(user.getName());
                    vo.setUserIcon(user.getIcon());
                }

            }
            //5.2封装回复信息
            InteractionReply reply = replyMap.get(question.getLatestAnswerId());
            if (reply != null) {
                vo.setLatestReplyContent(reply.getContent());
                if (!reply.getAnonymity()) {//不是
                    UserDTO user = userMap.get(reply.getUserId());
                    if (user != null) {
                        vo.setLatestReplyUser(user.getUsername());
                    }
                }
            }
            voList.add(vo);
        }

        return PageDTO.of(page, voList);
    }

    /**
     * 根据id查询问题详情
     *
     * @param id
     * @return
     */
    @Override
    public QuestionVO queryQuestionByid(Long id) {
        //1.查询InteractionQuestion
        InteractionQuestion question = getById(id);
        QuestionVO vo = BeanUtils.copyBean(question, QuestionVO.class);
        //2.判断是否匿名，不是，根据提问者的User_id查询用户信息，封装提问者的信息
        if (!question.getAnonymity() && !question.getHidden()) {
            UserDTO user = userClient.queryUserById(question.getUserId());
            if (user != null) {
                vo.setUserName(user.getName());
                vo.setUserIcon(user.getIcon());
            }
        }
        //封装好返回
        return vo;
    }

    /**
     * 根据id删除我的问题
     *
     * @param id
     */
    @Override
    @Transactional
    public void deletequestionByIds(Long id) {
        // 1.查询问题是否存在
        InteractionQuestion question = getById(id);
        ///- 判断是否是当前用户提问的
        Long userId = UserContext.getUser();
        if (!question.getUserId().equals(userId)) {
            throw new DbException("你不能删除这条评论");
        } else {
            boolean success = removeById(id);
            if (success) {
                replyMapper.selectreply(id);
            }
        }
        ///- 如果不是则报错
        ///- 如果是则删除问题
        ///- 然后删除问题下的回答及评论
    }


    /**
     * 分页查询问题（关于管理端）
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionAdminVO> queryQuestionPageAdmin(QuestionAdminPageQuery query) {
        String courseName = query.getCourseName();
        LocalDateTime beginTime = query.getBeginTime();
        LocalDateTime endTime = query.getEndTime();
        Integer status = query.getStatus();
        List<Long> coursesIds = null;
        //1.处理课程微服务
        if (StringUtils.isNotEmpty(courseName)) {
            coursesIds = searchClient.queryCoursesIdByName(courseName);
            if (CollUtils.isEmpty(coursesIds)) {
                return PageDTO.empty(0L, 0L);
            }
        }
        //2.分页查询问题，根据前端传过来的参数进行过滤
        Page<InteractionQuestion> page = lambdaQuery()
                .eq(status != null, InteractionQuestion::getStatus, status)
                .gt(beginTime != null, InteractionQuestion::getCreateTime, beginTime)
                .lt(endTime != null, InteractionQuestion::getCreateTime, endTime)
                .in(CollUtils.isNotEmpty(coursesIds), InteractionQuestion::getCourseId, coursesIds)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> questions = page.getRecords();
        if (CollUtils.isEmpty(questions)) {
            return PageDTO.empty(page);
        }
        Set<Long> cIds = new HashSet<>();
        Set<Long> cataIds = new HashSet<>();
        Set<Long> userIds = new HashSet<>();
        for (InteractionQuestion question : questions) {
            cIds.add(question.getCourseId());
            cataIds.add(question.getSectionId());
            cataIds.add(question.getChapterId());
            userIds.add(question.getUserId());
        }
        //3.根据userid查询用户集合
        Map<Long, UserDTO> userMap = new HashMap<>();
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        if (CollUtils.isNotEmpty(userDTOS)) {
            userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, l -> l));
        }

        //4.根据courseId查询课程信息
        Map<Long, CourseSimpleInfoDTO> courseMap = new HashMap<>();
        List<CourseSimpleInfoDTO> courseList = courseClient.getSimpleInfoList(cIds);
        if (CollUtils.isNotEmpty(courseList)) {
            courseMap = courseList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, l -> l));
        }
        //5.根据章节id查询章节信息
        Map<Long, CataSimpleInfoDTO> cataMap = new HashMap<>();
        List<CataSimpleInfoDTO> catalogueList = catalogueClient.batchQueryCatalogue(cataIds);
        if (CollUtils.isNotEmpty(catalogueList)) {
            cataMap = catalogueList.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, c -> c));
        }
        //6.遍历问题列表，封装Vo

        List<QuestionAdminVO> voList = new ArrayList<>();
        for (InteractionQuestion question : questions) {
            QuestionAdminVO vo = BeanUtils.copyBean(question, QuestionAdminVO.class);
            //6.1封装用户信息
            UserDTO userDTO = userMap.get(question.getUserId());
            if (userDTO != null) {
                vo.setUserName(userDTO.getName());
                CourseSimpleInfoDTO course = courseMap.get(question.getCourseId());
                if (course != null) {
                    vo.setCourseName(course.getName());
                    String categoryName = categoryCache.getCategoryNames(course.getCategoryIds());
                    vo.setCategoryName(categoryName);
                }
                CataSimpleInfoDTO chapter = cataMap.get(question.getChapterId());
                if (chapter != null) {
                    vo.setChapterName(chapter.getName());
                    CataSimpleInfoDTO section = cataMap.get(question.getSectionId());
                    if (section != null) {
                        vo.setSectionName(section.getName());
                        voList.add(vo);
                    }

                }
            }
        }

        return PageDTO.of(page, voList);
    }

    /**
     * 管理端隐藏或显示问题
     *
     * @param id
     * @param hidden
     */
    @Override
    @Transactional
    public void AdminhiddenQuestion(Long id, boolean hidden) {
        InteractionQuestion question = getById(id);
        if (question != null) {
            question.setHidden(hidden);
            question.setId(id);
            updateById(question);
        }
    }

    /**
     * 管理端根据id查询问题详情
     *
     * @param id
     * @return
     */
    @Override
    public QuestionAdminVO AdminqueryById(Long id) {
        InteractionQuestion lesson = getById(id);
        if (lesson == null) {
            throw new DbException("问题信息不存在");
        }
        QuestionAdminVO vo = BeanUtils.copyBean(lesson, QuestionAdminVO.class);

        Long userId = lesson.getUserId();
        UserDTO user = userClient.queryUserById(userId);
        if (user != null) {
            vo.setUserName(user.getUsername());
            vo.setUserIcon(user.getIcon());
        }
        Long courseId = lesson.getCourseId();
        CourseFullInfoDTO course = courseClient.getCourseInfoById(courseId, false, true);
        if (course != null) {
            vo.setCourseName(course.getName());
            String categoryNames = categoryCache.getCategoryNames(course.getCategoryIds());
            vo.setCategoryName(categoryNames);
            List<Long> teacherIds = course.getTeacherIds();
            List<UserDTO> userDTOS = userClient.queryUserByIds(teacherIds);
            if (CollUtils.isNotEmpty(userDTOS)) {
                UserDTO userDTO = userDTOS.get(0);
                String name1 = userDTO.getName();
                vo.setTeacherName(name1);
            }
            Set<Long> cataIds = new HashSet<>();
            cataIds.add(lesson.getChapterId());
            cataIds.add(lesson.getSectionId());
            List<CataSimpleInfoDTO> catalogueList = catalogueClient.batchQueryCatalogue(cataIds);
            Map<Long, CataSimpleInfoDTO> map = new HashMap<>();
            if (CollUtils.isNotEmpty(catalogueList)) {
                map = catalogueList.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, l -> l));
            }
            CataSimpleInfoDTO cataSimpleInfoDTO = map.get(lesson.getChapterId());
            vo.setChapterName(cataSimpleInfoDTO.getName());
            CataSimpleInfoDTO cataSimpleInfoDTO1 = map.get(lesson.getSectionId());
            vo.setSectionName(cataSimpleInfoDTO1.getName());
        }
        return vo;
    }

}
